package lib.bone.admin.controller.system;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.lang.Validator;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lib.bone.admin.anno.WebLog;
import lib.bone.admin.constant.MethodTypeConst;
import lib.bone.common.constant.ResponseCodeConst;
import lib.bone.common.core.domain.ResponseDTO;
import lib.bone.system.domain.dto.menu.MenuAddDTO;
import lib.bone.system.domain.dto.menu.MenuQueryDTO;
import lib.bone.system.domain.dto.menu.MenuUpdateDTO;
import lib.bone.system.domain.entity.SysMenu;
import lib.bone.system.service.SysMenuService;
import lib.bone.system.service.impl.SysMenuServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

/**
 * @author : kindear
 */

@Slf4j
@RestController
@RequestMapping("system")
@Api(tags = "系统菜单管理")
public class SysMenuController {
    @Autowired
    SysMenuService sysMenuService;

    @WebLog(module = "bone-system")
    @PostMapping("menus")
    @ApiOperation(value = "新增菜单",notes = "")
    @SaCheckPermission(value = "system_menu:add",orRole = "admin")
    public ResponseDTO saveMenu(@RequestBody @Validated MenuAddDTO menuAddDTO){
        //获取父ID
        Long parentId = menuAddDTO.getParentId();
        Optional<SysMenu> parentSysMenuOp = sysMenuService.getById(parentId);

        if(parentSysMenuOp.isPresent()){
            SysMenu parentMenu = parentSysMenuOp.get();
            SysMenu sysMenu = new SysMenu();
            BeanUtil.copyProperties(menuAddDTO,sysMenu, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
            sysMenu.setParent(parentMenu);
            //构建名称
            sysMenu.setParentName(parentMenu.getMenuName());
            return ResponseDTO.succData(sysMenuService.saveOne(sysMenu));
        }else {
            SysMenu sysMenu = new SysMenu();
            BeanUtil.copyProperties(menuAddDTO,sysMenu, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
            return ResponseDTO.succData(sysMenuService.saveOne(sysMenu));
        }
    }

    /**
     * 更新菜单列表
     */
    @WebLog(module = "bone-system",operate = MethodTypeConst.UPDATE)
    @PutMapping("menus")
    @ApiOperation(value = "更新菜单",notes = "传入数据需要携带ID")
    @SaCheckPermission(value = "system_menu:update",orRole = "admin")
    public ResponseDTO updateOne(@RequestBody @Validated MenuUpdateDTO menuUpdateDTO){
        Optional<SysMenu> menuOp = sysMenuService.getById(menuUpdateDTO.getId());
        if(menuOp.isPresent()){
            SysMenu sysMenu = menuOp.get();
            BeanUtil.copyProperties(menuUpdateDTO,sysMenu,CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
            //父级组件不存在
            if(Validator.isNotEmpty(sysMenu.getParent()) && !sysMenu.getParent().getId().equals(menuUpdateDTO.getParentId())){
                Optional<SysMenu> parentOp = sysMenuService.getById(menuUpdateDTO.getId());
                parentOp.ifPresent(sysMenu::sourceParent);
            }
            return ResponseDTO.succData(sysMenuService.saveOne(sysMenu));
        }else {
            return ResponseDTO.wrap(ResponseCodeConst.NOT_FOUND,"ID:["+menuUpdateDTO.getId()+"]对应菜单不存在!");
        }
    }


    @GetMapping("menus/{menuId}")
    @ApiOperation(value = "获取单个菜单",notes = "")
    @SaCheckPermission(value = "system_menu:list",orRole = "admin")
    public ResponseDTO<SysMenu> getOneMenu(@PathVariable("menuId") Long menuId){
        Optional<SysMenu> sysMenuOp = sysMenuService.getById(menuId);
        return sysMenuOp.map(ResponseDTO::succData).orElseGet(() -> ResponseDTO.wrap(ResponseCodeConst.NOT_FOUND, "不存在该菜单"));
    }

    @WebLog(module = "bone-system",operate = MethodTypeConst.DELETE)
    @DeleteMapping("menus/{menuId}")
    @ApiOperation(value = "删除单个菜单")
    @SaCheckPermission(value = "system_menu:delete",orRole = "admin")
    public ResponseDTO deleteOneMenu(@PathVariable("menuId") Long menuId){
        return sysMenuService.deleteById(menuId);
    }

    /** 获取菜单选择树 **/
    @GetMapping("menus/tree")
    @ApiOperation(value = "构建菜单树")
    @SaCheckPermission(value = "system_menu:list",orRole = "admin")
    public ResponseDTO buildMenuTree(){
        log.info("构建菜单树");
        List<SysMenu> sysMenus = sysMenuService.findByParent(null);
        return ResponseDTO.succData(sysMenuService.buildMenuTree(sysMenus));
    }
}
